Repository navigation
feat(rag): hybrid docs retrieval and readable ingest path - #249
Conversation
Dense-only search misses versions and release dates. Write hybrid Milvus rows, route queries in MCP, and keep ingest as importable modules in a slim image instead of pasted KFP source. Co-authored-by: Cursor <cursoragent@cursor.com> Signed-off-by: santhoshtoorpu <toorpusanthosh@gmail.com>
Keep this PR citation-only, put ModelConfig decode knobs back, read Milvus/embeddings URLs from env, and move issues/code pipelines out of extra/ next to a shared utils folder. Signed-off-by: santhoshtoorpu <toorpusanthosh@gmail.com> Co-authored-by: Cursor <cursoragent@cursor.com>
Public Flo can call search_kubeflow_code again. Test files match main so this PR stays code-only; OpenTelemetry stays out. Signed-off-by: santhoshtoorpu <toorpusanthosh@gmail.com> Co-authored-by: Cursor <cursoragent@cursor.com>
Wildcard COPY *.py would ship whatever happens to sit in the build context. Signed-off-by: santhoshtoorpu <toorpusanthosh@gmail.com> Co-authored-by: Cursor <cursoragent@cursor.com>
Do not bake cluster or localhost URLs into the MCP server. Signed-off-by: santhoshtoorpu <toorpusanthosh@gmail.com> Co-authored-by: Cursor <cursoragent@cursor.com>
Undo the live-folder delete so the PR no longer drops the main copy. OTEL stays out of this branch. Signed-off-by: santhoshtoorpu <toorpusanthosh@gmail.com> Co-authored-by: Cursor <cursoragent@cursor.com>
Keep hybrid RAG, structured ToolResult citations, and the v4 ingest path, while taking main's safer widget SSE/markdown path, query bounds, and Helm charts. Signed-off-by: santhoshtoorpu <toorpusanthosh@gmail.com>
Keep stop/cancel, overflow-safe code blocks, and Sources pills from the deployed website, and strip prose URLs so citations stay in the UI. Signed-off-by: santhoshtoorpu <toorpusanthosh@gmail.com>
e740e6e to
b92f87c
Compare
There was a problem hiding this comment.
I think this logic could be simplified, have you considered using tool to convert to MD. Can you check markdownify and frontmatter?
There was a problem hiding this comment.
Measured this on kubeflow/website default branch (master @ 8ee3017), content/en/docs/**/*.md only (220 files; 210 TOML +++, 10 YAML ---). 26 files have HTML <table, 11 have rowspan/colspan. Parse + chunk only (parse_frontmatter → build_milvus_records); no TEI/Milvus.
Before (custom +++/--- + rowspan grid) |
After (python-frontmatter + markdownify + html-table-rescuer tables) | |
|---|---|---|
| Files / exceptions | 220 / 0 | 220 / 0 |
title / weight present |
220 / 219 | 220 / 219 |
Chunks / median content_text |
2276 / 327 | 2180 / 351 |
Exact-match (path, chunk_index) |
— | 92.05% of shared keys; all 26 mismatches are the HTML-table pages |
No fail cases: <YOUR_HF_TOKEN> kept, fences intact, no empty titles, no table flattened off pipes. Hard slice (Katib config, release 26.03 date/component tables, style-guide): rowspan labels still repeat (AutoML Working Group ×2, Notebooks Working Group ×9).
Table bake-off on the 26 HTML-table files:
- custom grid: expands rowspan (good for RAG) but no GFM
---row - markdownify: 26/26 pipe tables; drops spanned cells
- html-to-markdown 1.16: 26/26; empty cells for rowspan (not a win)
- html2text: 25/26; flattens one table
- html-table-rescuer +
REPEAT_VALUE: 26/26; repeats rowspan labels like the old grid
Winner: python-frontmatter for YAML/TOML, html-table-rescuer for process_html_table, markdownify still for leftover HTML in clean_hugo_markdown. Still custom (no lib covers Hugo): fence/code/GFM stash, <YOUR_HF_TOKEN> stash, {{% alert %}} / shortcodes, fa-check icons.
That swap is in the worktree (hugo_ingest.py + ingest-image deps). Not committed/pushed until we get a go-ahead.
There was a problem hiding this comment.
Lol asked cursor to comment on this but yeah it seems to work lemme test a few more cases
|
Took a careful pass over this since it touches the ingest path I've been working in. Three findings, all reproduced against 1.
|
|
Hello @abhishekKokadwar thanks for the review. fixed the import in incremental PL. gotta refactor that one though |
Use python-frontmatter for YAML/TOML, html-table-rescuer for rowspan tables, and put utils/ on sys.path so incremental-pipeline.py compiles. Co-authored-by: Cursor <cursoragent@cursor.com> Signed-off-by: santhoshtoorpu <toorpusanthosh@gmail.com>
|
Thank you @SanthoshToorpu |
|
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: tarekabouzeid The full list of commands accepted by this bot can be found here. The pull request process is described here DetailsNeeds approval from an approver in each of these files:
Approvers can indicate their approval by writing |
Three test modules abort at collection on main:
ImportError: cannot import name 'clean_content' from 'utils'
(unknown location)
`pytest` exits 2, so the whole suite stops before running and both
workflows that invoke it are red.
kubeflow#249 moved `utils.py` into `pipelines/utils/`. These modules put only
`pipelines/` on `sys.path`, where the sibling directory of the same name
now shadows the module as a namespace package — `utils.__file__` is None
and `utils.__path__` is the directory, so no attribute resolves.
The pipelines themselves already handle this with a `_UTILS_DIR` entry
pointing at `pipelines/utils`; this applies the same thing to the tests
that import `utils` directly.
Recovers 72 tests across the four affected modules. The 7 failures and 63
errors that remain are pre-existing on dedbc84 and are not touched here:
`test_mcp_server.py` references `server.client`, removed when kubeflow#249 split
the MCP server, and `test_docs_pipeline.py` exercises the `store_milvus`
component that kubeflow#249 replaced with `utils/milvus_store.py`.
Signed-off-by: Abhishek <abhikokadwar2@gmail.com>
Every check on main has failed since #249/#261: - Pytest: the pipeline tests imported code_utils, issues_utils and utils from pipelines/, but #249 moved them to pipelines/utils/. Add that directory to sys.path, as the pipelines themselves do. - Widget tests: #249 intentionally stopped rendering links in the answer bubble (sources go to the Sources panel). Update the three tests to that contract: http(s) links render as their escaped label, other links stay inert text, inline code is untouched. - test_mcp_server.py targets pre-#249 internals (server.client, _init, _rerank_hits, ...) that no longer exist. Skip the module with the reason; it needs a rewrite against milvus_search/intent_router. - Compile: kubeflow-pipeline.py needs the ingest libraries (python-frontmatter, html-table-rescuer, ...). Compile the pipelines in their own virtualenv from pipelines/requirements.txt. - pipelines/requirements.txt could not be installed at all: kfp 2.17.0 pins requests==2.33.0 but the file pinned 2.34.2. - ruff format on milvus_search.py and server.py. Locally, with requirements-test.txt alone and with the MCP server requirements added: 112 passed, 69 skipped. All three pipelines compile in a clean virtualenv. ruff check and format pass. Signed-off-by: Rohit Kumar <rr7433446@gmail.com>
utils/hugo_ingest.py had no tests. kubeflow#249's test plan names tests/test_hugo_ingest.py, but the file was never committed (kubeflow#259). Only the production surface is covered. canonical_rag_ingest imports parse_frontmatter and process_html_table; clean_hugo_markdown has no caller, so testing it would add coverage that exercises nothing. Expectations are taken from the module's docstrings and inline comments, from how parse_canonical_document consumes the results, and from docs/RAG_V4_ARCHITECTURE.md, rather than from whatever the code currently returns: - parse_frontmatter: YAML and TOML give the title/description/weight that parse_canonical_document reads; a byte-order mark does not hide the frontmatter; missing keys stay absent; empty input is returned as-is; malformed frontmatter falls back to ({}, content) instead of aborting the run. - process_html_table: tables become GFM tables; rowspan values repeat into every spanned row (release tables); colspan keeps rows the same width; an escaped pipe does not add a column; text around and between tables stays off the table rows, as canonical_rag_ingest groups rows; the markdownify fallback still produces a table; text with no table is returned unchanged. The ingest dependencies were only in pipelines/requirements.txt and Dockerfile.pipeline, so the tests would have skipped in PR Safety. They are added to requirements-test.txt at the same pinned versions. Signed-off-by: Abhishek <abhikokadwar2@gmail.com>
Summary
release_date) and route queries in MCP instead of dense-only search.kubeflow-pipeline.pyis the DAG andmilvus_store.pywrites the collection (v=4is only the schema stamp).legacy/, and record the eval case indocs/RAG_V4_ARCHITECTURE.md.Test plan
pytest tests/test_mcp_server.py tests/test_kubeflow_pipeline_v4.py tests/test_canonical_rag_ingest.py tests/test_hugo_ingest.pypython docs-agent-mcp/pipelines/kubeflow-pipeline.pycompileskubeflow_docsdocs-rag-ingestimage built separately (not part of MCP CD)Made with Cursor